package com.ccc.dingtalk.service.dingtalk.impl;

import com.ccc.dingtalk.pojo.db.UserInfo;
import com.ccc.dingtalk.pojo.dingtalk.DingDept;
import com.ccc.dingtalk.pojo.dingtalk.DingUser;
import com.ccc.dingtalk.service.db.IUserInfoService;
import com.ccc.dingtalk.service.dingtalk.DeptService;
import com.ccc.dingtalk.service.dingtalk.UserService;
import com.ccc.dingtalk.util.DingtalkUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author superC
 * @version 1.0.0
 * @date 2023-08-09
 */

@Service
public class UserServiceImpl implements UserService {
    protected static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

    @Autowired
    private DingtalkUtil dingtalkUtil;

    @Autowired
    private DeptService deptService;

    @Autowired
    private IUserInfoService userInfoService;

    /**
     * 获取钉钉所有用户，并存储至DB
     *
     * @param accessToken
     * @return
     * @throws Exception
     */
    @Override
    public List<DingUser> getAllUsersAndStoreDb(String accessToken) throws Exception {
        // 1. 重新获取钉钉用户
        List<DingUser> list = this.getAllUsers(accessToken);
        if (!list.isEmpty()) {
            // 2. 先清空数据库中的用户
            this.clearDbUsers();
            // 3. 再存储至DB
            this.storeUsers2DB(list);
        }
        return list;
    }

    private void storeUsers2DB(List<DingUser> list) {
        list.forEach(dingUser -> {
            UserInfo userInfo = new UserInfo(dingUser.getUserid(), dingUser.getName());
            userInfoService.insert(userInfo);
        });
        logger.warn("【DB存储】-> 将所有钉钉用户存储至user表！");
    }

    private void clearDbUsers() {
        userInfoService.truncate();
        logger.warn("【DB存储】-> 清空user表！");
    }

    @Override
    public List<DingUser> getAllUsers(String accessToken) throws Exception {
        // 2. 获取所有部门
        List<DingDept> deptList = deptService.getDeptList(accessToken);
        if (deptList.isEmpty()) {
            throw new RuntimeException("当前企业没有设置部门，请先添加部门！");
        }

        // 3. 根据所有用户
        List<DingUser> userList = this.getAllUsers(accessToken, deptList);
        if (userList.isEmpty()) {
            throw new RuntimeException("没有查询到员工信息，请稍后重试！");
        }
        logger.info("【调用钉钉接口】-> 从钉钉获取用户，共计{}个", userList.size());
        return userList;
    }

    @Override
    public List<DingUser> getAllUsers(String accessToken, List<DingDept> deptList) {
        List<DingUser> list = new ArrayList<>();
        // 根据部门获取用户列表
        deptList.forEach(dept -> {
            List<DingUser> users = dingtalkUtil.getUserInfo(accessToken, dept.getDeptId());
            list.addAll(users);
        });
        return list;
    }

    @Override
    @Cacheable(value = "allUserIds", unless = "#result == null || #result.isEmpty()")
    public List<String> getAllUserIds(String accessToken) {
        // 1. 获取所有部门
        List<DingDept> deptList = deptService.getDeptList(accessToken);
        if (deptList.isEmpty()) {
            throw new RuntimeException("当前企业没有设置部门，请先添加部门！");
        }

        // 2. 根据部门获取所有用户ID集
        List<String> allUserIds = this.getAllUserIds(accessToken, deptList);
        if (allUserIds.isEmpty()) {
            throw new RuntimeException("没有获查询到员工信息，请稍后重试！");
        }
        return allUserIds;
    }

    @Override
    public List<String> getAllUserIds(String accessToken, List<DingDept> deptList) {
        List<String> allUserIds = new ArrayList<>();
        // 3. 根据部门获取用户ID集
        deptList.forEach(dept -> {
            List<String> userIds = dingtalkUtil.getUserIds(accessToken, dept.getDeptId());
            allUserIds.addAll(userIds);
        });
        return allUserIds;
    }

}
